import random
import threading
import time

import pygame

# 初始化
from base_api.base.MessageClass import Message

pygame.mixer.init()
# 是否有该模块的对象正在运行标志
global_isBusy_flag = False
# 锁，支持对isBusy_flag变量的读写多线程控制
lock = threading.Lock()


def set_isBusy_flag(isBusy_flag_this: bool):
    lock.acquire()
    global global_isBusy_flag
    global_isBusy_flag = isBusy_flag_this
    lock.release()


def get_chance():
    lock.acquire()
    flag = False
    global global_isBusy_flag
    if not global_isBusy_flag:
        global_isBusy_flag = True
        flag = True
    lock.release()
    return flag


"""
基于pygame.mixer的音频播放类
"""


class PygameMixerTask:
    def __init__(self):
        self.this_video_path = ''
        # 当前音频的开始节点，单位秒
        self.this_start_point = 0.0
        # 控制细粒度，默认为2，表示1/2秒的细粒度，要么播放这0.5秒的音频，要么就不播放。另一方面，也是每隔0.5秒反馈播放进度
        self.n = 2

        """
        为了方便处理，暂时来说，仅限多线程处理work_flag变量。
        细粒度控制、开始节点控制、播放模式切换等操作，都要求结束本次播放，然后重新启动
        """
        # 工作状态，True表示开启exploit的执行以及执行过程中，False表示停止exploit的执行以及执行完毕
        # 该状态量既受ui控制影响-启动/停止，也受内部影响-播放完成
        self.work_flag = False
        # 锁，用于处理线程问题
        self.this_lock = threading.Lock()

        # 输出通道，一般绑定到ui的信号signal中
        self.output_access = None

    def exploit(self):
        self.this_lock.acquire()
        self.work_flag = True
        self.this_lock.release()
        # 加载待播放音频
        pygame.mixer.music.load(self.this_video_path)
        # 播放
        pygame.mixer.music.play(start=self.this_start_point)

        # 阻塞线程等待播放
        while pygame.mixer.music.get_busy():
            # 等待1/n秒，n即设置的值
            pygame.time.Clock().tick(self.n)
            # 输出音频进度，单位毫秒
            self.output(Message(status=1, data=pygame.mixer.music.get_pos()))
            # 判断是否停止
            if not self.get_work_flag():
                pygame.mixer.music.stop()
                # 测试时，单纯的break可能导致无法停止播放，还是需要调用pygame的stop函数进行停止
                break
        # 解除音频文件占用，方便其它操作
        pygame.mixer.music.unload()

    def get_work_flag(self):

        self.this_lock.acquire()
        flag = self.work_flag
        self.this_lock.release()
        return flag

    def stop(self):
        self.this_lock.acquire()
        self.work_flag = False
        self.this_lock.release()

    """
    反馈音频的播放进度，以使ui同步显示，status=1，data为float类型
    data表示在指定音频文件中的位置
    """
    def output(self, msg: Message):
        self.this_lock.acquire()
        self.output_access(msg)
        self.this_lock.release()
